/*
 * Lenovo Group
 * Copyright (c) 2015-2016 All Rights Reserved.
 * Project Name: lmrp-android app
 * Create Time: 16-2-16 下午6:44
 */

package com.lenovo.mso2o.ui.fragment;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import com.jcodecraeer.xrecyclerview.ProgressStyle;
import com.jcodecraeer.xrecyclerview.XRecyclerView;
import com.lenovo.framework.FApplication;
import com.lenovo.framework.base.BaseActionBarMockingActivity;
import com.lenovo.framework.base.InjectableFragment;
import com.lenovo.framework.biz.ContextManager;
import com.lenovo.framework.conf.FConstants;
import com.lenovo.framework.entity.Res;
import com.lenovo.framework.rest.NetworkObserver;
import com.lenovo.framework.rx.RxBus;
import com.lenovo.framework.util.DLog;
import com.lenovo.framework.view.ContentLoaderView;
import com.lenovo.mso2o.MSApplication;
import com.lenovo.mso2o.R;
import com.lenovo.mso2o.conf.BizErrorCode;
import com.lenovo.mso2o.conf.ErrorCode;
import com.lenovo.mso2o.conf.MSConstants;
import com.lenovo.mso2o.entity.GrabResult;
import com.lenovo.mso2o.entity.Order;
import com.lenovo.mso2o.entity.OrderListRequest;
import com.lenovo.mso2o.entity.g.AutoSignOrder;
import com.lenovo.mso2o.entity.g.SlaAlarm;
import com.lenovo.mso2o.rest.OrderAPI;
import com.lenovo.mso2o.rest.ServiceGenerator;
import com.lenovo.mso2o.service.AutoSignService;
import com.lenovo.mso2o.service.SlaAlarmService;
import com.lenovo.mso2o.ui.WebActivity;
import com.lenovo.mso2o.ui.adapter.OrderAdapter;
import com.lenovo.mso2o.util.Utils;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

import butterknife.Bind;
import rx.Observable;
import rx.Scheduler;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action0;
import rx.functions.Action1;
import rx.schedulers.Schedulers;

public class OrderListFragment extends InjectableFragment implements ContentLoaderView.OnRefreshListener, ContentLoaderView.OnMoreListener, OrderAdapter.OnOrderSelectedListener, BaseActionBarMockingActivity.OnSearchListener, XRecyclerView.LoadingListener {

    public static final String KEY_ORDER_LIST = "key_order_list";
    public static final String REFRESH_HISTORY_ORDER_LIST = "refresh_history_list";

    // String itsmcode;	 	//是 工单系统标识
    // String user;		//否	 执行工单的工程师，默认是app登录用户账号
    // int page;		//否	 页码，从1开始，默认第一页
    // int limit;		//否	 每页的行数，默认10行
    // String condition;		//否	默认查询工程师当前未关闭的工单 当前支持的条件：timerange=from-end, 时间格式是yyyyMMddTHHmmss，若end为空表示到当前时间 status=-1|0|1|2|3|4,-1 - 所有，0 -待抢单，1 - 待接单，2 - 执行中，3 - 完成，4 - 已关单，默认是2 project=xxx
    // String sort;		//否 	默认按工单生成时间的倒序排列 多个排序字段逗号分隔，字段前加减号表示倒序
    // String includes;		//否	 设置可返回的字段，逗号分隔
    public final OrderListRequest request = new OrderListRequest();
    @Bind(R.id.content_loader)
    ContentLoaderView loaderView;
    @Bind(R.id.recycler)
    XRecyclerView recyclerView;
    public static final String REFRESH_ACTIVE_LSIT = "refresh_order_list";

    //变量命名
    OrderAPI orderAPI = ServiceGenerator.createService(OrderAPI.class);
    boolean hasLoaded = false;
    OrderAdapter adapter;
    int current_page = 1;
    private Subscription _subscription;
    //future actions scheduled to be executed
    Scheduler.Worker worker = Schedulers.newThread().createWorker();
    private Subscription refreshSubscription;
    Intent serviceIntent;
    private int type;
    private RxBus rxBus;

    public static Fragment newInstance(Context context, int type) {
        OrderListFragment fragment = new OrderListFragment();
        Bundle args = new Bundle();
        args.putInt(MSConstants.FragmentType.FRAGMENT_ORDERTYPE, type);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        if (outState != null) {
            if (adapter != null && adapter.getOrderList() == null)
                adapter.setListData(new ArrayList<Order>());
            if (adapter != null)
                outState.putSerializable(KEY_ORDER_LIST + type, adapter.getOrderList());
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = super.onCreateView(inflater, container, savedInstanceState);

        serviceIntent = new Intent(OrderListFragment.this.getActivity(), SlaAlarmService.class);
        rxBus = FApplication.getRxBus();
        orderAPI = ServiceGenerator.createService(OrderAPI.class);
        //计算距离
        recyclerView.setHasFixedSize(true);
        recyclerView.addItemDecoration(new SpaceItemDecoration(getItemSpace()));
        recyclerView.setItemAnimator(new DefaultItemAnimator());
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        recyclerView.setBackgroundColor(getResources().getColor(R.color.app_default_bg));
        recyclerView.setLoadingListener(this);
        recyclerView.setLoadingMoreEnabled(false);
        recyclerView.setRefreshProgressStyle(ProgressStyle.BallPulse);

        type = getArguments().getInt(MSConstants.FragmentType.FRAGMENT_ORDERTYPE);
        initViews(type, savedInstanceState);
        return view;
    }

    private void initViews(final int type, Bundle savedInstanceState) {
        switch (type) {
            case MSConstants.FragmentType.FRAGMENT_GRABORDERS:
                request.setStatus(MSConstants.ListParamConstants.listType_grab);
                break;

            case MSConstants.FragmentType.FRAGMENT_RECEIVEORDERS:
                request.setStatus(MSConstants.ListParamConstants.listType_receive);

                break;
            case MSConstants.FragmentType.FRAGMENT_ACTIVORDERS:
                request.setStatus(MSConstants.ListParamConstants.listType_live);
                break;
            case MSConstants.FragmentType.FRAGMENT_HISTORYORDERS:
                request.setStatus(MSConstants.ListParamConstants.listType_history);
                break;
        }
        adapter = new OrderAdapter(type, worker, this);
        adapter.setOnOrderSelectedListener(this);

        loaderView.setAdapter(adapter, type);
        loaderView.setOnRefreshListener(this);
        loaderView.setMoreListener(this);
        rxBus.toObserverable()
                .compose(this.bindToLifecycle())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<Object>() {
                    @Override
                    public void call(Object o) {
                        if (o instanceof Order) {
                            if (adapter != null) {
                                List<Order> list = adapter.getOrderList();
                                for (Order obj : list) {
                                    if (((Order) o).getTicketid().equals(obj.getTicketid())) {
                                        adapter.getOrderList().remove(obj);
                                        adapter.notifyDataSetChanged();
                                        break;
                                    }
                                }
                            }
                        } else if (REFRESH_HISTORY_ORDER_LIST.equals(o)) {
                            if (MSConstants.FragmentType.FRAGMENT_HISTORYORDERS == type) {
                                loadData(request);
                            }
                        } else if (REFRESH_ACTIVE_LSIT.equals(o)) {
                            if (MSConstants.FragmentType.FRAGMENT_ACTIVORDERS == type) {
                                loadData(request);
                            }
                        }
                    }
                });
    }

    @Override
    public int provideContentRes() {
        return R.layout.fragment_list;
    }


    @Override
    public void onDestroyView() {
        if (_subscription != null && !_subscription.isUnsubscribed()) {
            _subscription.unsubscribe();
        }
        if (worker != null && !worker.isUnsubscribed()) {
            worker.unsubscribe();
        }

        super.onDestroyView();
    }

    @Override
    protected void onFragmentInVisible(Bundle savedInstanceState) {
        if (refreshSubscription != null)
            refreshSubscription.unsubscribe();
    }

    @Override
    protected void onFragmentVisible(Bundle savedInstanceState) {
        if (adapter.getItemCount() == 0) {
            if (savedInstanceState != null) {
                ArrayList<Order> anchorList = (ArrayList<Order>) savedInstanceState.getSerializable(KEY_ORDER_LIST + type);
                adapter.setListData(anchorList);
            } else {
                loadData(request);
            }
        } else {
            countDownList();
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        type = getArguments().getInt(MSConstants.FragmentType.FRAGMENT_ORDERTYPE, MSConstants.FragmentType.FRAGMENT_ACTIVORDERS);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
    }

    @Override
    public void onAttach(Context activity) {
        super.onAttach(activity);
    }

    public void loadData(final OrderListRequest request) {
        //活动工单一次全部加载，用来监控与提醒?
        /*
        if (MSConstants.FragmentType.FRAGMENT_ACTIVORDERS == type) {
            request.setLimit(Integer.MAX_VALUE);
        }
        */
        if (!hasLoaded) {
            //TODO load from cache
        }
        if (_subscription == null || _subscription.isUnsubscribed()) {
            if (refreshSubscription != null)
                refreshSubscription.unsubscribe();
            _subscription = orderAPI.orderList(request)
                    .compose(this.<Res<ArrayList<Order>>>bindToLifecycle())
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .doOnTerminate(new Action0() {
                        @Override
                        public void call() {
                            _subscription = null;
                        }
                    })
                    .unsubscribeOn(Schedulers.io())// unsubscribe after network io
                    .subscribe(new NetworkObserver<Res<ArrayList<Order>>>() {
                        @Override
                        public void onSuccess(final Res<ArrayList<Order>> arrayListResult) {
                            if (arrayListResult.getEcode() != 0) {
                                ErrorCode bizErrorCode = BizErrorCode.errorMap.get(arrayListResult.getEcode());
                                if (bizErrorCode != null) {
                                    onFailure(bizErrorCode.getReason());
                                } else {
                                    if (arrayListResult.getReason() != null && !TextUtils.isEmpty(arrayListResult.getReason()))
                                        onFailure(arrayListResult.getReason());
                                    else
                                        onFailure(getString(R.string.unknown_error));
                                }
                                return;
                            }
                            int page = request.getPage();
                            //success
                            ArrayList<Order> orderList = arrayListResult.getResult();
                            //设置倒计时时间
                            //adapter.setTenEnd(System.currentTimeMillis());
                            if (adapter == null)
                                adapter = new OrderAdapter(type, worker, OrderListFragment.this);
                            if (page == MSConstants.ListParamConstants.FIRST_PAGE) {
                                adapter.setListData(orderList);
                            } else {
                                adapter.addListData(orderList);
                            }
                            if (type == MSConstants.FragmentType.FRAGMENT_ACTIVORDERS && orderList != null && orderList.size() > 0) {
                                //开启service
                                //SlaAlarmService.mOrders = adapter.getOrderList();
                                storeAndStartService(adapter.getOrderList(), OrderListFragment.this.getActivity(), serviceIntent);
                            }
                            hasLoaded = true;
                            adapter.notifyDataSetChanged();
                            if ((orderList.size() > 0)) {
                                countDownList();
                            }

                            if (orderList.size() < MSConstants.ListParamConstants.pageSize_default) {
                                current_page = page;
                                loaderView.setPage(page, current_page);//最后一页数据少于约定数据量，停止加载
                            } else {
                                current_page = page + 1;
                                loaderView.setPage(page, current_page);//设置当前页和最后一页
                            }
                        }

                        @Override
                        public void onFailure(String tip) {
                            if (loaderView != null) {
                                loaderView.notifyLoadFailed(new Exception(tip));
                            }
                        }
                    });
        }
    }

    private void storeAndStartService(final ArrayList<Order> orderList, final FragmentActivity activity, final Intent serviceIntent) {
        if (orderList != null && orderList.size() > 0) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    MSApplication.getDaoSession().getSlaAlarmDao().deleteAll();
                    for (Order order : orderList) {
                        //用一下原来用过的AutoSignOrder实例
                        SlaAlarm sla = new SlaAlarm();
                        sla.setTickedid(order.getTicketid());
                        sla.setDesone(order.getDescription()[0]);
                        sla.setDestwo(order.getDescription()[1]);
                        sla.setAlarmtime(order.getStatus().getValue()[0]);
                        sla.setOvertime(order.getStatus().getValue()[1]);
                        MSApplication.getDaoSession().getSlaAlarmDao().insert(sla);
                    }
                    activity.startService(serviceIntent);
                }
            }).start();
        }
    }

    private void countDownList() {
        if (type == MSConstants.FragmentType.FRAGMENT_GRABORDERS) {
            if (refreshSubscription != null)
                refreshSubscription.unsubscribe();
            refreshSubscription = worker.schedulePeriodically(new Action0() {
                @Override
                public void call() {
                    new Handler(Looper.getMainLooper()).post(new Runnable() {
                        @Override
                        public void run() {
                            adapter.notifyDataSetChanged();
                        }
                    });
                }
            }, 0, 1, TimeUnit.SECONDS);
        }
    }

    @Override
    public void onRefresh(boolean fromSwipe) {//这是swipeLayout的回调
        request.setPage(MSConstants.ListParamConstants.page_default);
        current_page = MSConstants.ListParamConstants.page_default;
        loadData(request);
    }

    @Override
    public void onMore(int page) {
        request.setPage(page);
        loadData(request);
    }

    @Override
    public void onRefresh() {//这是xRecyclerview的回调
        request.setPage(MSConstants.ListParamConstants.page_default);
        current_page = MSConstants.ListParamConstants.page_default;
        loadData(request);
        recyclerView.refreshComplete();
    }

    @Override
    public void onLoadMore() {//这是xRecyclerview的回调
        //这是xRecyclerview的回调
        /*new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
            @Override
            public void run() {
                Log.e("LEE", "onLoadMore finished...");
                request.setPage(page);
                loadData(request);
                recyclerView.loadMoreComplete();
            }
        }, 3000);*/
    }


    @Override
    public void onOrderSelected(final Order order, final Context context) {
        final Intent intent = new Intent(ContextManager.context(), WebActivity.class);
        intent.putExtra(WebActivity.ORDER, order);
        final int type = getArguments().getInt(MSConstants.FragmentType.FRAGMENT_ORDERTYPE);
        if (type == MSConstants.FragmentType.FRAGMENT_GRABORDERS) {
            OrderAPI api = ServiceGenerator.createService(OrderAPI.class);
            final Observable<Res<GrabResult>> grabres = api.updateGrabRes(order.getTicketid());
            grabres.compose(this.<Res<GrabResult>>bindToLifecycle())
                    .subscribeOn(Schedulers.io())
                    .unsubscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new NetworkObserver<Res<GrabResult>>() {
                        @Override
                        public void onSuccess(Res<GrabResult> grabResultRes) {
                            if (grabResultRes.getEcode() != 0) {
                                ErrorCode bizErrorCode = BizErrorCode.errorMap.get(grabResultRes.getEcode());
                                if (bizErrorCode != null) {
                                    onFailure(bizErrorCode.getReason());
                                } else {
                                    onFailure(context.getString(R.string.unknown_error));
                                }
                                return;
                            }
                            if (grabResultRes.getResult() != null && grabResultRes.getResult().getSuccess() == 0) {
                                //已经被别人抢单
                                Toast.makeText(OrderListFragment.this.getContext(), R.string.grabed_by_other, Toast.LENGTH_SHORT).show();
                                RxBus rxBus = FApplication.getRxBus();
                                rxBus.send(order);
                                return;
                            }
                            //抢单中或者抢到了？进入详情
                            intent.putExtra(FConstants.X5WEBVIEW_INITIAL_URL, String.format(MSConstants.APIConstants.ORDER_DETAIL_URL, order.getTicketid()));
                            getActivity().startActivityForResult(intent, type);
                        }

                        @Override
                        public void onFailure(String tip) {
                            Toast.makeText(context, tip, Toast.LENGTH_SHORT).show();
                        }
                    });
            return;
        } else if (type == MSConstants.FragmentType.FRAGMENT_HISTORYORDERS) {
            String ticketType = order.getTickettype() == null ? "" : order.getTickettype();
            if (ticketType.equalsIgnoreCase("巡检单")) {
                intent.putExtra(FConstants.X5WEBVIEW_INITIAL_URL, String.format(MSConstants.APIConstants.INSPECTION_ORDER_DETAIL_URL, order.getTicketid()));
                DLog.d("order detail", String.format(MSConstants.APIConstants.INSPECTION_ORDER_DETAIL_URL, order.getTicketid()));
            } else {
                intent.putExtra(FConstants.X5WEBVIEW_INITIAL_URL, String.format(MSConstants.APIConstants.CLOSED_ORDER_DETAIL_URL, order.getTicketid()));
                DLog.d("order detail", String.format(MSConstants.APIConstants.CLOSED_ORDER_DETAIL_URL, order.getTicketid()));
            }
        } else {
            intent.putExtra(FConstants.X5WEBVIEW_INITIAL_URL, String.format(MSConstants.APIConstants.ORDER_DETAIL_URL, order.getTicketid()));
            DLog.d("order detail", String.format(MSConstants.APIConstants.ORDER_DETAIL_URL, order.getTicketid()));
        }
        ((Activity) context).startActivityForResult(intent, type);
    }

    /**
     * 设置数据加载条件
     *
     * @param reload
     */
    public void initParams(OrderListRequest request, boolean reload) {
        this.request.clear();
        this.request.from(request);
        if (reload)
            loadData(request);
    }

    @Override
    public void onTextChanged(String text) {
        request.setKey(text);
        if (adapter != null) {
            adapter.filterList(text);
            adapter.notifyDataSetChanged();
        }
    }

    @Override
    public void onSearchEnter() {
        if (adapter != null) {
            loadData(request);
        }
    }

    @Override
    public void onEnterSearchMode() {
    }

    @Override
    public void onExitSearchMode() {
        request.setKey(null);
        if (getActivity() != null) {
            if (((BaseActionBarMockingActivity) getActivity()).isSearching()
                    && adapter != null) {
                adapter.filterList(null);
                adapter.notifyDataSetChanged();
            }
        }
    }

    /**
     * 设置RecycleView之间的间距
     */

    public class SpaceItemDecoration extends RecyclerView.ItemDecoration {
        int space;

        public SpaceItemDecoration(int space) {
            this.space = space;

        }

        @Override
        public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {

            if (parent.getChildPosition(view) != 0)
                outRect.top = space;
        }
    }

    public int getItemSpace() {
        DisplayMetrics dm = new DisplayMetrics();
        getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm);
        int space = (int) (dm.density * 36 / 2.75);
        return space;
    }

    @Override
    public void onConfirmClick() {
        loadData(request);
    }
}
